package com.wusuowei.auth.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wusuowei.common.annotation.Log;
import com.wusuowei.common.config.WuSuoWeiConfig;
import com.wusuowei.common.constant.BusinessTypeEnum;
import com.wusuowei.common.constant.CacheConstants;
import com.wusuowei.common.core.RedisCache;
import com.wusuowei.common.model.po.ComLoginLog;
import com.wusuowei.common.model.po.ComUser;
import com.wusuowei.common.utils.R;
import com.wusuowei.common.utils.SecurityUserUtil;
import com.wusuowei.ucenter.model.po.SysMenu;
import com.wusuowei.ucenter.model.po.SysUser;
import com.wusuowei.ucenter.model.po.SysUserRole;
import com.wusuowei.ucenter.model.vo.UserVo;
import com.wusuowei.ucenter.service.ISysMenuService;
import com.wusuowei.ucenter.service.ISysUserRoleService;
import com.wusuowei.ucenter.service.ISysUserService;
import com.wusuowei.ucenter.utils.LoginInfoUtil;
import com.wusuowei.ucenter.utils.RSAUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
public class SecurityUserController {

    @Autowired
    private WuSuoWeiConfig wuSuoWeiConfig;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private ISysUserRoleService userRoleService;
    @Autowired
    ApplicationContext applicationContext;
    @Autowired
    private RedisCache redisCache;

    @PostMapping("/login")
    public R login(@RequestHeader("Authorization") String authorization, HttpServletRequest request){
        HashMap<String, Object> resmap = new HashMap<>();
        String[] split = authorization.split("\\s+");
        String access_token = split[1];
        List<SysMenu> sysMenus = null;
        ComUser comUser = null;
        try {
            comUser = SecurityUserUtil.getSecurityUser();
            sysMenus = menuService.getUserMenus(comUser.getId());
            resmap.put("user", comUser);
            resmap.put("menus", sysMenus);
            resmap.put("permissions", menuService.getPermission(comUser.getId()));
            //记录token，使token有状态，实现了踢人下线
            redisCache.setCacheObject(CacheConstants.ACCESS_TOKEN_KEY+comUser.getId(),access_token,wuSuoWeiConfig.getRefreshTokenexpire(), TimeUnit.SECONDS);
            //记录登录日志
            ComLoginLog logininfor = LoginInfoUtil.recordSuccessLoginInfo(comUser, request, "登录成功");
            //记录在线人数
            redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY+comUser.getId());
            logininfor.setUid(comUser.getId());
            redisCache.setCacheObject(CacheConstants.LOGIN_TOKEN_KEY+comUser.getId(),logininfor,wuSuoWeiConfig.getRefreshTokenexpire(), TimeUnit.SECONDS);
        } catch (Exception e) {
            LoginInfoUtil.recordErrorLoginInfo(comUser, request, e.getMessage());
            return R.error("登录失败！");
        }
        return R.ok("登录成功！").setData(resmap);
    }

    @Log(title = "用户注册", businessType = BusinessTypeEnum.INSERT)
    @PostMapping("/register")
    public R register(@RequestBody UserVo userVo) {
        String md5Password = passwordEncoder.encode(userVo.getPassword());
        SysUser sysUser = new SysUser();
        sysUser.setUsername(userVo.getUsername());
        sysUser.setNickname(userVo.getUsername());
        sysUser.setPassword(md5Password);
        userService.save(sysUser);

        //设置默认角色
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(sysUser.getId());
        sysUserRole.setRoleId(2);
        userRoleService.save(sysUserRole);

        return R.ok();
    }

    @PostMapping("/logout")
    public R logout(Authentication authentication) {
        String userJson = (String) authentication.getPrincipal();
        SysUser sysUser = JSON.parseObject(userJson, SysUser.class);
        redisCache.deleteObject(CacheConstants.ACCESS_TOKEN_KEY+sysUser.getId());
        redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY+sysUser.getId());
        return R.ok();
    }

    /**
     * 登录前生成公钥，用于加密
     * @return
     * @throws Exception
     */
    @PostMapping("/getPublicKey")
    public R getPublicKey(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception{
        String publicKey = RSAUtils.generateBase64PublicKey();
        return  R.ok().setData(publicKey);
    }

    /**
     * @description 检查用户名
     * @param username 用户名
     * @return {@link R }
     * @author LGY
     * @date 2023/03/24 21:09
     */
    @GetMapping("/check")
    public R countByUsername(@RequestParam String username) {
        long count = userService.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        if (count != 0) {
            return R.error("用户名已存在");
        }
        return R.ok();
    }


}
